#include "search_tab.h"
#include <gtk/gtk.h>
#include "../../gui_al.h"
#include "../../settings.h"
#include "../../gui_io.h"
#include "../../search.h"
#include "../../second.h"
#include "../../srch_pane.h"
#include "../../cryptography.h"
#include "../../xml.h"
#include "../../journal.h"
#include "../../plugins.h"
#include "../../threads.h"
#include "../../tabs.h"




/*  Search Interfacing  */
int elog_gui_al_addResult(struct elog_srch_result *item);
//Adds a result to the search list, returns 0 on success

int elog_gui_al_clearResults();
//Returns 0 upon successfully clearing search results.

int elog_gui_al_caseSensitive(int set);
//Pre:  set is 1,0,-1
//Post:  If set is -1, returns current value, if it is 0,1 it will set it.

int elog_gui_al_lyric(int set);
//Pre:  set is 1,0,-1
//Post:  If set is -1, returns current value, if it is 0,1 it will set it.

float elog_gui_al_srchAccuracy(float set);
//Pre:  set is -1-1
//Post:  If set is < 0; retrieves current value; otherwise it sets it.






char **_srch_tab_list_res = NULL;
int _srch_tab_list_res_n = 0;


gboolean __srchtab_tree_foreach(GtkTreeModel * model, GtkTreePath * path,
				GtkTreeIter * iter, gpointer data)
{
	char *name;
	char *str_path;
	gtk_tree_model_get(model, iter, 2, &name, 4, &str_path, -1);
	if (!(str_path) || !(name))
		return TRUE;

	struct elog_xml_doc *doc = elog_crypt_open_dry(str_path);
	if (doc) {
		int *res = elog_srch_listResults(doc->text, (char *) data);
		if (res[0] >= 0) {
			elog_srch_pane_add_item(name,
						_srch_tab_list_res_n);
			if (_srch_tab_list_res_n < 127)
				_srch_tab_list_res[_srch_tab_list_res_n] =
				    str_path;
			++_srch_tab_list_res_n;
			if (_srch_tab_list_res_n >= 127) {
				free(name);
				free(res);
				return TRUE;
			}
		}
		free(res);
		elog_xml_doc_free(doc);
	}
	free(name);
	return FALSE;
}

int _elog_tab_srch_res(void *p)
{
	elog_gui_al_lock();
	elog_srch_pane_clear();
	_srch_tab_list_res_n = 0;
	int c;
	for (c = 0; _srch_tab_list_res[c]; ++c)
		free(_srch_tab_list_res[c]);

	gtk_tree_model_foreach(GTK_TREE_MODEL(_srchTree),
			       __srchtab_tree_foreach, p);
	_srch_tab_list_res[_srch_tab_list_res_n] = NULL;

	elog_gui_al_unlock();
	char *term = (char *) p;
	free(term);
	return 0;
}

int _tab_scnd_hide(void *p)
{ //this function is necessary to solve problems with searches
	//during collapses with gtk...
	gtk_widget_hide(_res_srch_window);
	return 0;
}

int elog_tab_srch_srch()
{
	const char *term = gtk_entry_get_text(GTK_ENTRY(_menu_srch_entry));
	if (term) {
		if (strlen(term) > 0) {
			gtk_widget_show(_res_srch_window);
		} else
			elog_scnd_run(_tab_scnd_hide, "hide");
	} else
		elog_scnd_run(_tab_scnd_hide, "hide");

	if (!(_srch_tab_list_res)) {
		_srch_tab_list_res =
		    malloc((sizeof *_srch_tab_list_res) * 128);
		_srch_tab_list_res[0] = NULL;
	}

	char *term1;
	elog_sp_cat(&term1, term, NULL);
	elog_scnd_run_arg(_elog_tab_srch_res, "srch tab", term1);

	return 0;
}
gboolean    _srch_list_foreach2		      (GtkTreeModel *model,
                                             GtkTreePath *path,
                                             GtkTreeIter *iter,
                                             gpointer data)
{
	char *p;
	char *check = (char *)data;
	gtk_tree_model_get(model, iter, 4, &p, -1);

	if (strcmp(p, check) == 0) {
		free(p);
		gtk_tree_view_set_cursor(GTK_TREE_VIEW(_srchTreeView),
								path, NULL, FALSE);
		return TRUE;
	}
	return FALSE;                                	
}


int elog_tab_srch_res(int n)
{
	if (n < _srch_tab_list_res_n) {
		gtk_tree_model_foreach(GTK_TREE_MODEL(_srchTree),
							_srch_list_foreach2, (gpointer) _srch_tab_list_res[n]);

	}
	else
		return 1;
	return 0;
}

int elog_tab_srch_cut()
{
	if (gtk_widget_is_focus(_srchTxt)) {
		gtk_editable_cut_clipboard(GTK_EDITABLE(_srchTxt));
		return 0;
	}
	if (gtk_widget_is_focus(_srchTreeView))
		return elog_tab_srch_copy();

	return 1;
}

int elog_tab_srch_copy()
{
	if (gtk_widget_is_focus(_srchTxt)) {
		gtk_editable_copy_clipboard(GTK_EDITABLE(_srchTxt));
		return 0;
	}
	if (gtk_widget_is_focus(_srchTreeView)) {
		char *entry = elog_srch_tab_getDay();
		if (!entry)
			return 1;
		char *clip;
		elog_sp_cat(&clip, "LOCATION://", entry, NULL);
		free(entry);
		elog_gui_al_clipBoard(clip);
		free(clip);
		return 0;
	}

	return 1;
}

int elog_tab_srch_paste()
{
	if (gtk_widget_is_focus(_srchTxt)) {
		gtk_editable_paste_clipboard(GTK_EDITABLE(_srchTxt));
		return 0;
	}
	if (gtk_widget_is_focus(_srchTreeView)) {
		return 0;	//placeholder
	}

	return 1;
}

int elog_tab_srch_delete()
{
	return 0;
}

char *elog_srch_tab_getDay()
{
	GtkTreeModel *model = (GtkTreeModel *) _srchTree;
	GtkTreePath *tree_path;
	GtkTreeViewColumn *trash;
	gtk_tree_view_get_cursor(GTK_TREE_VIEW(_srchTreeView), &tree_path,
				 &trash);
	if (!tree_path)
		return NULL;

	char *str_path = (char *) gtk_tree_path_to_string(tree_path);
	gtk_tree_path_free(tree_path);
	GtkTreeIter iter;
	gtk_tree_model_get_iter_from_string(model, &iter, str_path);
	free(str_path);

	char *title;
	char *path;
	gtk_tree_model_get(model, &iter, 0, &title, 4, &path, -1);
	free(title);
	return path;
}

void __search_function(void *in)
{
	elog_gui_io_search(in);
}

void on_srch_lyric_change(GtkRange * range, gpointer user_data)
{
	//  if (elog_srch_status() != ELOG_SRCH_STAT_GO)
	//   return;

	elog_srch_lyric(elog_gui_al_lyric(-1));
	/*char *txt = elog_gui_al_searchText(NULL);
	   if (strlen(txt) > 0)
	   traverSearch(elog_set_get_str("path"), txt, __search_function); */

}

void on_search_btn_activate(GtkButton * button, gpointer user_data)
{
	elog_gui_al_setLockMode(ELOG_GUI_AL_LOCK_CALLBACK);
	if (elog_srch_status() != ELOG_SRCH_STAT_GO)
		return;

	elog_srch_lyric(elog_gui_al_lyric(-1));
	char *txt = (char *)gtk_entry_get_text(GTK_ENTRY(_srchTxt));
	if (strlen(txt) > 0)
		traverSearch(elog_set_get_str("path"), txt,
			     __search_function);
	elog_gui_al_setLockMode(ELOG_GUI_AL_LOCKED);
}



void on_srch_entry_activate(GtkEntry * entry, gpointer user_data)
{
	elog_gui_al_setLockMode(ELOG_GUI_AL_LOCK_CALLBACK);
	if (elog_srch_status() != ELOG_SRCH_STAT_GO)
		return;
	elog_srch_accuracy(elog_gui_al_srchAccuracy(-1.0));
	elog_srch_caseSensitive(elog_gui_al_caseSensitive(-1));

	char *txt = (char *) gtk_entry_get_text(entry);
	if (strlen(txt) > 0)
		traverSearch(elog_set_get_str("path"), txt,
			     __search_function);
	elog_gui_al_setLockMode(ELOG_GUI_AL_LOCKED);
}

void on_srch_accuracy_change(GtkRange * range, gpointer user_data)
{
	//    if (elog_srch_status() != ELOG_SRCH_STAT_GO)
	//    return;
	elog_gui_al_setLockMode(ELOG_GUI_AL_LOCK_CALLBACK);
	elog_srch_accuracy(elog_gui_al_srchAccuracy(-1.0));
	elog_gui_al_setLockMode(ELOG_GUI_AL_LOCKED);

	/*      char *txt = elog_gui_al_searchText(NULL);
	   if (strlen(txt) > 0)
	   traverSearch(elog_set_get_str("path"), txt, __search_function); */

}

void
on_srch_sensitivity_change(GtkToggleButton * togglebutton,
			   gpointer user_data)
{
	//if (elog_srch_status() != ELOG_SRCH_STAT_GO)
	//    return;
	elog_gui_al_setLockMode(ELOG_GUI_AL_LOCK_CALLBACK);
	elog_srch_caseSensitive(elog_gui_al_caseSensitive(-1));
	elog_gui_al_setLockMode(ELOG_GUI_AL_LOCKED);
	/*      char *txt = elog_gui_al_searchText(NULL);
	   if (strlen(txt) > 0)
	   traverSearch(elog_set_get_str("path"), txt, __search_function); */

}

char *_srch_last_term = NULL;
int _encrypt = 0;

struct elog_thread *_searchThread = NULL;
void (*_srch_tab_functor) (void *);


void _srch_tab_middleman_functor(void *p)
{
	struct elog_srch_result *res = (struct elog_srch_result *) p;
	elog_gui_al_lock();
	elog_gui_al_addResult(res);
	elog_gui_al_unlock();
	_srch_tab_functor(p);
}


int __srch_run_srch(void *p)
{
	if (elog_tab_current() == 2)
		elog_tab_srch_srch();
	return elog_scnd_still("search");
}
int __run_incr_srch(void *p)
{
	return elog_srch_incremental_search((struct elog_srch_instr *) p);
}
void traverSearch(const char *dir, const char *term,
		  void (*functor) (void *))
{	
	elog_srch_setDir(dir);
	if (term) {
		if (_srch_last_term)
			free(_srch_last_term);

		elog_sp_cat(&_srch_last_term, term, NULL);
	}
	if (_srch_last_term) {
		_srch_tab_functor = functor;

		struct elog_srch_instr *i = elog_srch_instr_new();
		i->term = _srch_last_term;
		i->directory = elog_srch_setDir(NULL);
		i->func = _srch_tab_middleman_functor;
		//i->lyrical = _srch_lyrical;
		//  i->caseSensitive = _case_Sensitive;
		//i->accuracy = _allowed_diff;
		elog_gui_al_lock();
		elog_gui_al_clearResults();
		elog_gui_al_unlock();
		
		elog_gui_io_view_clear_results();
		elog_scnd_run_arg(__run_incr_srch, "search", i);

		elog_scnd_run(__srch_run_srch, "refresh");
		gtk_entry_set_text(GTK_ENTRY(_srchTxt), term);
	}
}
int elog_srch_status()
{
	if (_searchThread == NULL)
		return ELOG_SRCH_STAT_GO;
	if (_searchThread->state == ELOG_THRD_STATE_BUSY)
		return ELOG_SRCH_STAT_BUSY;

	return ELOG_SRCH_STAT_GO;
}
GtkWidget *elog_srch_initialize()
{
	GtkWidget *hpaned2;
	GtkWidget *treeview1;
	GtkWidget *srch_entry;
	GtkWidget *scrolledwindow2;
	GtkWidget *vbox3;
	GtkWidget *srch_lbl;

	hpaned2 = gtk_hpaned_new();

	vbox3 = gtk_vbox_new(FALSE, 0);
	gtk_paned_pack1(GTK_PANED(hpaned2), vbox3, FALSE, TRUE);

	srch_lbl = gtk_label_new(_("Search:"));
	gtk_box_pack_start(GTK_BOX(vbox3), srch_lbl, FALSE, FALSE, 0);

	srch_entry = gtk_entry_new();
	gtk_box_pack_start(GTK_BOX(vbox3), srch_entry, FALSE, FALSE, 0);

	int srchCaseSensitiveVal = elog_set_get_int("SearchCase");
	if (srchCaseSensitiveVal == -1)
		srchCaseSensitiveVal = 0;
	_srchCaseSentive =
	    gtk_check_button_new_with_label(_("Case Sensitive"));
	if (srchCaseSensitiveVal == 1)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
					     (_srchCaseSentive), TRUE);
	else
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
					     (_srchCaseSentive), FALSE);

	gtk_box_pack_start(GTK_BOX(vbox3), _srchCaseSentive, FALSE, FALSE,
			   0);

	GtkWidget *srchAccuracyLbl =
	    gtk_label_new(_("\nSearch Accuracy:"));

	gtk_box_pack_start(GTK_BOX(vbox3), srchAccuracyLbl, FALSE, FALSE,
			   0);

	_srchAccuracy = gtk_hscale_new_with_range(.05, 1.0, .15);
	float srchAccuracyVal = (float) elog_set_get_int("SearchAccur");
	if (srchAccuracyVal > 0)
		srchAccuracyVal = srchAccuracyVal / 10.0;
	else
		srchAccuracyVal = 0.9;
	gtk_range_set_value(GTK_RANGE(_srchAccuracy), srchAccuracyVal);
	//gtk_wiget_show(_srchAccuracy);
	gtk_box_pack_start(GTK_BOX(vbox3), _srchAccuracy, FALSE, FALSE, 0);


	int srchLyric = elog_set_get_int("SearchLyric");
	if (srchLyric == -1)
		srchLyric = 0;
	_srchLyric =
	    gtk_check_button_new_with_label(_("Only look in verses"));
	if (srchLyric == 1)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_srchLyric),
					     TRUE);
	else
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_srchLyric),
					     FALSE);

	//gtk_wiget_show(_srchLyric);
	gtk_box_pack_start(GTK_BOX(vbox3), _srchLyric, FALSE, FALSE, 0);



	GtkWidget *search_btn = gtk_button_new_from_stock(GTK_STOCK_FIND);
	//gtk_wiget_show(search_btn);
	gtk_box_pack_end(GTK_BOX(vbox3), search_btn, FALSE, FALSE, 0);



	scrolledwindow2 = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW
				       (scrolledwindow2),
				       GTK_POLICY_AUTOMATIC,
				       GTK_POLICY_AUTOMATIC);
	//gtk_wiget_show (scrolledwindow2);
	gtk_paned_pack2(GTK_PANED(hpaned2), scrolledwindow2, TRUE, TRUE);
	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
					    (scrolledwindow2),
					    GTK_SHADOW_IN);

	treeview1 = gtk_tree_view_new();
	//gtk_wiget_show (treeview1);
	gtk_container_add(GTK_CONTAINER(scrolledwindow2), treeview1);



	g_signal_connect((gpointer) _srchAccuracy, "value-changed",
			 G_CALLBACK(on_srch_accuracy_change), NULL);
	g_signal_connect((gpointer) _srchCaseSentive, "toggled",
			 G_CALLBACK(on_srch_sensitivity_change), NULL);
	g_signal_connect((gpointer) _srchLyric, "toggled",
			 G_CALLBACK(on_srch_lyric_change), NULL);
	g_signal_connect((gpointer) srch_entry, "activate",
			 G_CALLBACK(on_srch_entry_activate), NULL);
	g_signal_connect((gpointer) treeview1, "row_activated",
			 G_CALLBACK(on_treeview1_row_activated), NULL);
	g_signal_connect((gpointer) search_btn, "clicked",
			 G_CALLBACK(on_search_btn_activate), NULL);

	_srchTxt = srch_entry;
	_srchTreeView = treeview1;

	GtkCellRenderer *renderer;
	GtkCellRenderer *rendererOccur;
	GtkCellRenderer *rendererYear;
	GtkCellRenderer *rendererMonth;
	GtkTreeViewColumn *col;
	GtkTreeViewColumn *colOccur;
	GtkTreeViewColumn *colYear;
	GtkTreeViewColumn *colMonth;



	col = gtk_tree_view_column_new();
	colOccur = gtk_tree_view_column_new();
	colYear = gtk_tree_view_column_new();
	colMonth = gtk_tree_view_column_new();

	gtk_tree_view_column_set_title(col, "Name");
	gtk_tree_view_column_set_title(colOccur, "Occurances");
	gtk_tree_view_column_set_title(colYear, "Year");
	gtk_tree_view_column_set_title(colMonth, "Month");

	gtk_tree_view_column_set_reorderable(col, TRUE);
	gtk_tree_view_column_set_reorderable(colOccur, TRUE);
	gtk_tree_view_column_set_reorderable(colYear, TRUE);
	gtk_tree_view_column_set_reorderable(colMonth, TRUE);

	gtk_tree_view_append_column(GTK_TREE_VIEW(treeview1), colYear);
	gtk_tree_view_append_column(GTK_TREE_VIEW(treeview1), colMonth);
	gtk_tree_view_append_column(GTK_TREE_VIEW(treeview1), col);
	gtk_tree_view_append_column(GTK_TREE_VIEW(treeview1), colOccur);

	renderer = gtk_cell_renderer_text_new();
	rendererOccur = gtk_cell_renderer_text_new();
	rendererYear = gtk_cell_renderer_text_new();
	rendererMonth = gtk_cell_renderer_text_new();

	gtk_tree_view_column_pack_start(col, renderer, TRUE);
	gtk_tree_view_column_pack_start(colOccur, rendererOccur, TRUE);
	gtk_tree_view_column_pack_start(colYear, rendererYear, TRUE);
	gtk_tree_view_column_pack_start(colMonth, rendererMonth, TRUE);

	gtk_tree_view_column_add_attribute(col, renderer, "text",
					   COL_SRCH_ENTRY);
	gtk_tree_view_column_add_attribute(colOccur, rendererOccur, "text",
					   COL_SRCH_ENTRY2);
	gtk_tree_view_column_add_attribute(colYear, rendererYear, "text",
					   COL_SRCH_YEAR);
	gtk_tree_view_column_add_attribute(colMonth, rendererMonth, "text",
					   COL_SRCH_MONTH);




	_srchTree =
	    (GtkWidget *) gtk_list_store_new(NUM_SRCH_COLS, G_TYPE_STRING,
					     G_TYPE_STRING, G_TYPE_STRING,
					     G_TYPE_STRING, G_TYPE_STRING);

	gtk_tree_view_set_model(GTK_TREE_VIEW(treeview1),
				GTK_TREE_MODEL(_srchTree));

	_srchIter = malloc(sizeof *_srchIter);
	gtk_list_store_append(GTK_LIST_STORE(_srchTree), _srchIter);
	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(_srchTree),
					     COL_SRCH_ENTRY2,
					     GTK_SORT_ASCENDING);

	return hpaned2;

}


/*********Old abstraction layer functions*****/
int elog_gui_al_addResult(struct elog_srch_result *item)
{

	gtk_list_store_append(GTK_LIST_STORE(_srchTree), _srchIter);
	const char *month = elog_mnth_str(item->month);
	char *year = elog_sp_shortToString(item->year);
	char *occur = elog_sp_shortToString(item->occurances);
	gtk_list_store_set(GTK_LIST_STORE(_srchTree), _srchIter, 0, year,
			   1, month, 2, item->name, 3, occur, 4,
			   item->fileName, -1);

	free(year);

	return 0;
}
int elog_gui_al_clearResults()
{

	gtk_list_store_clear(GTK_LIST_STORE(_srchTree));

	return 0;
}

int elog_gui_al_caseSensitive(int set)
{
	if (set < 0) {
		if (gtk_toggle_button_get_active
		    (GTK_TOGGLE_BUTTON(_srchCaseSentive)) == TRUE) {

			return 1;
		} else {

			return 0;
		}
	}
	if (set > 0)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
					     (_srchCaseSentive), TRUE);
	else
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
					     (_srchCaseSentive), FALSE);


	return -1;
}

int elog_gui_al_lyric(int set)
{
	if (set < 0) {
		if (gtk_toggle_button_get_active
		    (GTK_TOGGLE_BUTTON(_srchLyric))
		    == TRUE) {

			return 1;
		} else {

			return 0;
		}
	}
	if (set > 0)
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_srchLyric),
					     TRUE);
	else
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_srchLyric),
					     FALSE);


	return -1;
}


float elog_gui_al_srchAccuracy(float set)
{

	if (set < 0.0) {
		float ret =
		    (float) gtk_range_get_value(GTK_RANGE(_srchAccuracy));

		return ret;
	}
	gtk_range_set_value(GTK_RANGE(_srchAccuracy), (gdouble) set);

	return -1.0;
}

/************************************/

